# tasks.py
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")

import django

django.setup()

import threading
import asyncio
import random
import time

from link.models import Link
from linkutil.get_url import my_get_link
from logs.models import Log, LinkLog, now_Data

# from link.api import run_link_by_id

class TaskManager:
    def __init__(self):
        self.tasks_queue = {}  # 存放任务的队列
        self.stop_event = threading.Event()  # 用来停止所有任务的事件

    def run_task_in_thread(self, task_id, delay):
        """
        在新的线程中运行任务
        """
        loop = asyncio.new_event_loop()  # 为每个线程创建新的事件循环
        asyncio.set_event_loop(loop)  # 设置当前线程的事件循环
        loop.run_until_complete(self.async_task(task_id, delay * 60 + random.randint(1,60)))

    async def async_task(self, task_id, delay):
        """
        模拟异步任务，每个任务有不同的延迟
        """
        while not self.tasks_queue[task_id].is_set():  # 检查是否需要停止任务
            pass #print(f"任务 {task_id} 开始执行，延迟 {delay} 秒")
            if isinstance(task_id, str):
                task_id = int(task_id)
            link = Link.objects.filter(LinkId=task_id).first()
            if not link.Swith:
                pass #print(f"任务{link.LinkId}关闭")
                break
            # 将其转为字典列表
            linkData = link.to_dict()

            try:
                pass #print("try : ", 123)
                startTime = now_Data()
                final_url, log_des = await my_get_link(linkData.get("OfferLink"), linkData.get("TargetNation"), linkData.get("redirect"), linkData.get("URLldentifiers"), referrer=linkData.get("referrer"))
                pass #print("final_url", final_url)
                pass #print("log_des", log_des)
                pass #print("try : ", 1234)
                if log_des.get("flag", False):
                    link.finalUrl=final_url
                    link.fail_num = 0
                    link.save()
                else:
                    link.fail_num += 1
                    if link.fail_num > 5:
                        link.Swith = False
                    link.save()
                endTime = now_Data()
                pass #print("startTime", startTime)
                pass #print("endTime", endTime)
                pass #print("try : ", 1235)
                pass #print()
                LinkLog.objects.create(
                    LinkID=int(task_id),
                    LogOptionDetail = f"""
                    运行LinkId: {task_id}
                    详细过程: {log_des}""",
                    LinkInfo=log_des["linkInfo"],
                    LinkURls=log_des["urls"],
                    ProxyInfo=log_des["proxyInfo"],
                    FinalUrl=log_des.get("final_url", ""),
                    LogResult=LinkLog.LogResultChoices.SUCCESS.name if log_des.get("flag", "") else LinkLog.LogResultChoices.FAIL.name,
                    LogStartTime=startTime,
                    LogEndTime=endTime
                )
                # Log.create_Log(
                #     userId=1,
                #     LogResult=Log.LogResultChoices.SUCCESS.name,
                #     LogOptionDetail=f"""
                #     运行LinkId: {task_id}
                #     详细过程: {log_des}""",
                # )
                pass #print("try : ", 1236)
            except Exception as e:
                pass #print("e: ", e)
            
            # run_link_by_id(task_id)
            await asyncio.sleep(delay)
            pass #print(f"任务 {task_id} 执行完毕")


    def add_task(self, task_id, delay):
        """
        添加新任务到队列并启动
        :param task_id: 任务ID
        :param delay: 任务的延迟时间
        """
        if task_id in self.tasks_queue:
            pass #print(f"任务 {task_id} 已存在，无法重复添加")
            return
        pass #print(f"添加任务 {task_id} 到队列")
        stop_event = threading.Event()  # 创建独立的停止事件
        self.tasks_queue[task_id] = stop_event  # 将停止事件添加到任务字典中
        thread = threading.Thread(target=self.run_task_in_thread, args=(task_id, delay))
        thread.start()  # 启动线程

    def remove_task(self, task_id):
        """
        删除任务的方式是通过设置stop_event来控制每个线程的停止
        :param task_id: 任务ID
        """
        if task_id not in self.tasks_queue:
            pass #print(f"任务 {task_id} 不存在")
            return

        pass #print(f"停止任务 {task_id}")
        self.tasks_queue[task_id].set()  # 设置停止事件
        del self.tasks_queue[task_id]  # 从任务字典中移除任务

    def remove_all_tasks(self):
        """
        停止所有任务
        """
        pass #print("停止所有任务")
        for task_id in list(self.tasks_queue.keys()):  # 使用 list 避免迭代时修改字典
            self.stop_task(task_id)

    def create_tasks(self, num_tasks, interval_range=(1, 5)):
        """
        创建多个任务，每个任务按时间间隔执行
        :param num_tasks: 任务数量
        :param interval_range: 任务的时间间隔，默认为(1, 5)秒之间
        """
        for task_id in range(1, num_tasks + 1):
            # 随机生成任务延迟时间
            delay = random.randint(interval_range[0], interval_range[1])
            self.add_task(task_id, delay)